﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using X = Adjunct.Framework.Nuspec.XNames.Package.Metadata.Dependencies;

namespace Adjunct.Framework.Nuspec
{
	/// <summary>
	/// This class is a collection of NuspecDependency
	/// </summary>
	/// <remarks></remarks>
	public class NuspecDependencies : List<NuspecDependency>
	{
		/// <summary>
		/// Adds the specified id.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <param name="version">The version.</param>
		/// <remarks></remarks>
		public void Add(string id, string version = null)
		{
			Add(new NuspecDependency(id, version));
		}

		/// <summary>
		/// Clones this instance.
		/// </summary>
		/// <returns></returns>
		/// <remarks></remarks>
		public NuspecDependencies Clone()
		{
			NuspecDependencies clone = new NuspecDependencies();
			clone.AddRange(this.Select(dependency => dependency.Clone()));
			return clone;
		}

		/// <summary>
		/// Performs an explicit conversion from <see cref="Adjunct.Framework.Nuspec.NuspecDependencies"/> to
		/// <see cref="System.Xml.Linq.XElement"/>.
		/// </summary>
		/// <param name="dependencies">The dependencies.</param>
		/// <returns>Returns null if the dependencies are null or empty for sparse xml.</returns>
		/// <remarks></remarks>
		public static explicit operator XElement(NuspecDependencies dependencies)
		{
			if ((dependencies == null) || (dependencies.Count == 0))
			{
				return null;
			}
			return new XElement(X.ElementName, dependencies.OrderBy(d => d.Id).Select(d => (XElement)d));
		}

		/// <summary>
		/// Performs an explicit conversion from <see cref="System.Xml.Linq.XElement"/> to
		/// <see cref="Adjunct.Framework.Nuspec.NuspecDependencies"/>.
		/// </summary>
		/// <param name="element">The element.</param>
		/// <returns>Always returns an instance so that the consumer doesn't have to see if one was created.</returns>
		/// <remarks></remarks>
		public static explicit operator NuspecDependencies(XElement element)
		{
			NuspecDependencies dependencies = new NuspecDependencies();
			if (element != null)
			{
				element.EnsureElementNameIs(X.ElementName);
				dependencies.AddRange(element.Elements(X.Dependency.ElementName).Select(child => (NuspecDependency)child));
			}
			return dependencies;
		}
	}
}